# -*- coding: utf-8 -*-
import hashlib
import json
import time
import uuid
from datetime import datetime

import requests
import xmltodict
from dicttoxml import dicttoxml
from django.conf import settings
from django.http import HttpResponse
from django.template import Context
from django.template.loader import get_template
from django.views.decorators.http import require_GET, require_POST

from common.cache.redis_cache import get_cache_html, get_recharge_risk, get_recharge_daily
from common.level_strategy import db as level_db
from common.level_strategy import handle as level_handle
from common.mch import handler as mch_handler
from common.order import db as order_db
from common.order import handler as order_handler
from common.utils import exceptions as err
from common.utils import track_logging
from common.utils.api import check_params, get_client_ip
from common.utils.decorator import response_wrapper
from common.utils.metrics import Metric

_LOGGER = track_logging.getLogger(__name__)


@require_POST
@response_wrapper
def create(request):
    """
    统一下单接口
    PARAMS:
      sdk_version: sdk version code
      service: 服务类型, WECHAT/ALIPAY
      mch_id: 商户号
      out_trade_no: 商户订单号
      body: 商品描述
      total_fee: 总金额
      mch_create_ip: 订单生成的机器ip
      notify_url: 异步通知接口
      sign: 签名
      extra: 附加信息，回调时返回
      chn_type: 通道类型，可选，用户制定通道
      user_id: 商户用户id，可空
      channel_id: 通道ID 指定通道补单时使用 为空时走原有逻辑
    """
    metric = Metric(_LOGGER)
    params = request.POST.dict()
    _LOGGER.info('order create params: %s', params)
    check_params(params, ['sdk_version', 'service', 'mch_id',
                          'out_trade_no', 'body', 'total_fee', 'mch_create_ip',
                          'notify_url', 'sign'], param_type_dct={
        'mch_id': basestring,
        'out_trade_no': basestring,
    })
    sign = params['sign']
    params.pop('sign')
    mch_id = params['mch_id']
    calculated_sign = mch_handler.generate_sign(mch_id, params)
    if sign != calculated_sign:
        raise err.AuthenticateError('sign error')
    metric.measure('sign')
    # create charge (call third interface)
    params['mch_create_ip'] = get_client_ip(request)
    params.update(sign=sign)
    extra = json.loads(params['extra'])
    user_info = extra.get('user_info', None)
    user_id = user_info.get('user_id', None) if user_info else None
    _LOGGER.info('create_charge_user_info: %s', user_info)
    channel_level = -1
    if user_info:
        try:
            metric.measure('begin level')
            user_info['level'], channel_level = level_handle.clac_user_level(user_info, mch_id)
            _LOGGER.info('user_level : %s, channel_level:%s', user_info['level'], channel_level)
            user_info['mch_id'] = mch_id
            level_db.upsert_mch_user(user_info)
            metric.measure('end level')
        except Exception as e:
            _LOGGER.info('charge_create level_db_upsert_mch_user Exception, %s', e)

    # 判断是否为限制名单
    is_risk = get_recharge_risk(mch_id, user_id)
    daily_risk_count = int(get_recharge_daily(mch_id, user_id).get('count', 0))

    # 判断状态是否能上分请求
    metric.measure('begin status')
    charge_status = level_db.get_mch_user_status(mch_id, user_id)
    metric.measure('end status')

    if is_risk or not charge_status or daily_risk_count >= 3:
        _LOGGER.info('forbidden mch_id: %s, user_id: %s', mch_id, user_id)
        return err.AuthenticateError('mch_id: %s, user_id: %s, forbidden' % (mch_id, user_id))

    charge_info = order_handler.create_charge(params, metric, channel_level=channel_level)
    metric.end()
    return charge_info


@require_GET
@response_wrapper
def get_channel_pay_url(request):
    params = request.GET.dict()
    return order_handler.get_channel_pay_result(params['channel_id'])


@require_POST
@response_wrapper
def query(request):
    """
    订单查询接口
    """
    params = request.POST.dict()
    check_params(params, ['mch_id',
                          'out_trade_no', 'sign'], param_type_dct={
        'mch_id': basestring,
        'out_trade_no': basestring,
    })
    sign = params['sign']
    params.pop('sign')
    mch_id = params['mch_id']
    out_trade_no = params['out_trade_no']
    calculated_sign = mch_handler.generate_sign(mch_id, params)
    if sign != calculated_sign:
        raise err.AuthenticateError('sign error')
    order_info = order_handler.get_order(mch_id, out_trade_no)
    return order_info


def construct_notify_data(pay, status):
    discount = float(json.loads(pay.extend or '{}').get('discount', 0))
    total_fee = float(pay.total_fee) + discount
    data = {
        'trade_no': pay.id,
        'mch_id': pay.mch_id,
        'trade_type': pay.channel_type,
        'out_trade_no': pay.out_trade_no,
        'pay_result': status,
        'total_fee': total_fee,
        'extra': pay.extra,
    }
    sign = mch_handler.generate_sign(pay.mch_id, data)
    data.update({'sign': sign})
    return data


@require_POST
@response_wrapper
def notify_order_status(request):
    """
    订单状态主动通知
    """
    params = request.POST.dict()
    _LOGGER.info('notify_order_status: %s', params)
    check_params(params, ['mch_id', 'status',
                          'out_trade_no', 'sign'], param_type_dct={
        'mch_id': basestring,
        'out_trade_no': basestring,
    })
    sign = params['sign']
    status = params['status']
    params.pop('sign')
    mch_id = params['mch_id']
    out_trade_no = params['out_trade_no']
    calculated_sign = mch_handler.generate_sign(mch_id, params)
    if sign != calculated_sign:
        raise err.AuthenticateError('sign error')
    order_info = order_db.get_order(int(mch_id), int(out_trade_no))
    data = construct_notify_data(order_info, status)
    notify_url = order_info.notify_url
    res = requests.post(notify_url, data=data, timeout=5).text
    _LOGGER.info('notify_order_status rsp: %s', res)
    return {'result': res}


@require_GET
def get_cache_page(request, cache_id):
    return HttpResponse(get_cache_html(cache_id))


def generate_sign(parameter, key):
    s = ''
    for k in sorted(parameter.keys()):
        if parameter[k] != '' and parameter[k] != None:
            s += '%s=%s&' % (k, parameter[k])
    s += 'key=%s' % key
    m = hashlib.md5()
    m.update(s.encode('utf8'))
    sign = m.hexdigest().upper()
    return sign


def _get_pay_type(type):
    if type == 'qq':
        return 'pay.tenpay.native'
    elif type == 'alipay':
        return 'pay.alipay.native'
    else:
        return 'pay.weixin.native'


APP_CONF = {
    'chenfenglingmin': {
        'mch_id': '101590290881',
        'appkey': 'f8bb3def9a75d62acf83166d17f8ff96',
    },
    'chenfenglinghua': {
        'mch_id': '101530291006',
        'appkey': '74b1b61d64fdc0655eef953addd77513',
    },
    'liangxunhaigong': {
        'mch_id': '101590453540',
        'appkey': 'ff8b2bac2834ade277aa308f6e620113',
    },
    'liangxunhaijiao': {
        'mch_id': '101520444586',
        'appkey': '98423a9e9276af212bf91c365eca3ff4',
    },
    'chenyulingzhao': {
        'mch_id': '101590443168',
        'appkey': 'f4e578a9dc8504bc27d3a4f9c6d17404',
    },
    'chenyulingjiao': {
        'mch_id': '101570327532',
        'appkey': 'f4bf0587ed9341aa06ea7c2128ff27ee',
    },
    'libingjian': {
        'mch_id': '101540291922',
        'appkey': 'd86d2007987400de1f1e7380af985dbd',
    },
    'libingzhao': {
        'mch_id': '101500446833',
        'appkey': '8e4408a2c1dfd8a64e99ce8c81f9b4bc',
    },
    'zhoudabo': {
        'mch_id': '101500328676',
        'appkey': 'c8dab6cd884dd4c9fee2c6c7247c2a05',
    },
    'jiangyun': {
        'mch_id': '101540298922',
        'appkey': '7bf487778ead6695fe50f3d01f581f24',
    },
    'zhaoyasijian': {
        'mch_id': '101580446014',
        'appkey': 'a13c8318d7e93915d2f1d1a3ecf0736a',
    },
    'chenjunyingzhao': {
        'mch_id': '101570441915',
        'appkey': 'b1194eea2024ed4cbf6d7d9755842639',
    },
    'chenjunyinghua': {
        'mch_id': '101500292049',
        'appkey': '68ca1174ceba7c022f42e6aca77d102e',
    },
    'zhaoyasigong': {
        'mch_id': '101520291532',
        'appkey': 'aa5ffd2994ca79f1986b5388258a0fce',
    },
    'jiangleijian': {
        'mch_id': '101500545850',
        'appkey': 'c048b632a7f51154aa0674c082906a21',
    },
    'jiangleigong': {
        'mch_id': '101580444487',
        'appkey': '572ded16375424a4babfb29c216ea92c',
    },
    'linjiangdongnong': {
        'mch_id': '101500446188',
        'appkey': 'bcf4705af443148e1ae6093b49a3cc06',
    },
    'linjiangdonggong': {
        'mch_id': '101530445288',
        'appkey': 'dd8ebda8df62406120380484ed914d87',
    },
    'zhaozhenlinnong': {
        'mch_id': '101530293067',
        'appkey': '1cb0da02cf1873cc489f4ccf17b7a1d4',
    },
    'wenjiarong': {
        'mch_id': '101500298479',
        'appkey': '7ad643175f2e9d183e7cf51f8f7848a6',
    },
    'longhao': {
        'mch_id': '101580328635',
        'appkey': '34e2f4b291e6a074508851867f3a4dcf',
    },
    'lilu': {
        'mch_id': '101560297699',
        'appkey': '1c0ffde2172a80064b0dea091d804f20',
    },
    'zhaozhenlingong': {
        'mch_id': '101550326963',
        'appkey': 'a4e78b0224649924d5a641d1001036f9',
    },
    'linhuixupu': {
        'mch_id': '101540298183',
        'appkey': '3892d683579c50af2b942e65331858ce',
    },
    'xiaoguozhongjiao': {
        'mch_id': '101570293517',
        'appkey': '8f421490e57093203b00b530318b8017',
    },
    'linhuixugong': {
        'mch_id': '101520297239',
        'appkey': '7f2cb649cf3c6b3dcb798fe7a3a1d723',
    },
    'chenfenglinghua_gd': {
        'mch_id': '105570117426',
        'appkey': '6f8bcf17fc1e4c80d3c2f7bd765da81b',
    },
    'chenjunyingzhao_gd': {
        'mch_id': '105560116977',
        'appkey': 'e8d2df01b936e54c1db06e789e878a72',
    },
    'chenyulingjiao_gd': {
        'mch_id': '105570120034',
        'appkey': '8aba81016f3d9d23d3fb98014d659cc6',
    },
    'chenyulingzhao_gd': {
        'mch_id': '105550120193',
        'appkey': 'ec96c670484d108b5091c1621c184377',
    },
    'chenyulingzhong_gd': {
        'mch_id': '105520119869',
        'appkey': 'ffc21b1b1f3ac3c471de3f877c6b8492',
    },
    'xiaoguozhongjiao_gd': {
        'mch_id': '105560119737',
        'appkey': '6358a72551532628172f690135d6b7fe',
    },
    'linjiangdongmin_gd': {
        'mch_id': '105560119736',
        'appkey': '6dbaedcc17f682ae90a761d4a3bf8f90',
    },
    'zhaoyasizhong_gd': {
        'mch_id': '105530120446',
        'appkey': '6a9fa6cbd70dc71ab7b2a37ddc4ffb5f',
    },
    'libingjian_gd': {
        'mch_id': '105580120072',
        'appkey': '518ce33cb61bc41d24b070433e2ef94c',
    },
    'linhuixugong_gd': {
        'mch_id': '105550120249',
        'appkey': '760a45fc3c64340410cd39775df771b8',
    },
    'zhongwenzao_gd': {
        'mch_id': '105500120200',
        'appkey': '2111249fbb5bba46f7165e58ac89b901',
    },
    'linbingzhao_gd': {
        'mch_id': '105520119889',
        'appkey': '43610dccd595e6a9fb64bb1cf5a915a1',
    },
    'linhuixupu_gd': {
        'mch_id': '105570120061',
        'appkey': 'b3d59a6b9e517a1e25b6f068e6698b8b',
    },

    'chenyulingzhong': {
        'mch_id': '101550456828',
        'appkey': '2651919efbe4fb21cc309ea6efe86204',
    },
    'linjiangdongmin': {
        'mch_id': '101520458224',
        'appkey': 'c09009d57d1f9e656cd6aab40006d5f3',
    },
    'zhaoyasizhong': {
        'mch_id': '101590457845',
        'appkey': '83b2d3c066636c3f041dbba7fc408282',
    },
    'yangweiming': {
        'mch_id': '101570467504',
        'appkey': '07919273e89d933de6fef9e821261d74',
    },
    'zhongwenzao': {
        'mch_id': '101540466619',
        'appkey': '1b8be3850c90a01f83b186b00ac457e7',
    },
    'liangxunhainong': {
        'mch_id': '101530459154',
        'appkey': '26e1731f5286afe9b055abf4250a125c',
    },
    'chenfenglingzhao': {
        'mch_id': '101530456377',
        'appkey': '18ac8a40111e3809e0fd27721672fe75',
    },
    'chenjunyingzhong': {
        'mch_id': '101560455076',
        'appkey': 'c9cdfa3e89f4f61fdd2c7a022ea26d84',
    },
    'liangxunhaizhao': {
        'mch_id': '101500459150',
        'appkey': 'a90f3b53914c1ca70064d2837f3f4995',
    },

    'chenfenglinghua001': {
        'mch_id': '101530291006',
        'appkey': '74b1b61d64fdc0655eef953addd77513',
    },
    'chenjunyingzhao001': {
        'mch_id': '101570290952',
        'appkey': 'fa1967afb07dac30603c457a56fb7185',
    },
    'chenjunyinghua001': {
        'mch_id': '101500292049',
        'appkey': '68ca1174ceba7c022f42e6aca77d102e',
    },
    'liangxunhaigong001': {
        'mch_id': '101570290938',
        'appkey': '45776ff9a7b1253b3f059d6ae285c188',
    },
    'liangxunhaijiao001': {
        'mch_id': '101560327597',
        'appkey': '91cc7c123bafdf89d92e9fafb72c8c53',
    },
    'zhaoyasijian001': {
        'mch_id': '101560288335',
        'appkey': '4d3e9dd06225cc8e5b7af5ab64fe394c',
    },
    'jiangleijian001': {
        'mch_id': '101540294009',
        'appkey': '3502a8f57fb8a33775ae8416d69e71fd',
    },
    'jiangleigong001': {
        'mch_id': '101580444487',
        'appkey': '572ded16375424a4babfb29c216ea92c',
    },
    'linjiangdongnong001': {
        'mch_id': '101580295565',
        'appkey': 'fe44e7b7046c9fc4a22b7a753d91a2ef',
    },
    'linjiangdonggong001': {
        'mch_id': '101590327310',
        'appkey': '248070f24ef0feec9cf90561b80a80ab',
    },
    'chenyulingzhao001': {
        'mch_id': '101580288822',
        'appkey': 'd6da46b58e05a64dd1226a2140e8ca09',
    },
    'libingzhao001': {
        'mch_id': '101540291923',
        'appkey': 'f18971ceadf344a3400b508e5acaf054',
    },
    'jiangleigong002': {
        'mch_id': '101550292592',
        'appkey': '3897388437751a31dbd78b21b65ee26e',
    },
    'liangxunhainong001': {
        'mch_id': '101540568554',
        'appkey': 'e117e614f2794e3d5d49a0ef1ae83615',
    },
    'chenfenglingzhao001': {
        'mch_id': '101510569921',
        'appkey': 'aaeb62bb9a3ae17af13e0f49f7892115',
    },
    'chenjunyingzhong001': {
        'mch_id': '101550569259',
        'appkey': '92cff92ff26db6db3271a0ee912c4077',
    },
    'jiangyun001': {
        'mch_id': '101590570429',
        'appkey': 'a78ac5c38ec50eeb823eb67cd5362363',
    },
    'chenyulingjiao001': {
        'mch_id': '101560569261',
        'appkey': '39354adbc38d8f44ffc1902bbe6b79bc',
    },
    'wenjiarong001': {
        'mch_id': '101590578017',
        'appkey': '097883425812387168042ca46d465a92',
    },
    'zhaozhenlingong001': {
        'mch_id': '101530581158',
        'appkey': '99f66ebc8e99909cb5eff6cbda3da76e',
    },
    'linjiangdonggong002': {
        'mch_id': '101570578417',
        'appkey': 'e748bfd4973c6bdee59b17ce181318c7',
    },
    'linjiangdongmin001': {
        'mch_id': '101540579260',
        'appkey': 'fc12d6c41ae436921878f0dccdcc3031',
    },
    'chenyulingzhong001': {
        'mch_id': '101580581190',
        'appkey': 'b3a6eeacd40a1ef75e56827318439ade',
    },
    'linhuixugong001': {
        'mch_id': '101500578776',
        'appkey': '42a6bc54e2d572c76eee8ece48f9a482',
    },
    'liangxunhaizhao001': {
        'mch_id': '101530567420',
        'appkey': '7a65a8cc6249e67ad4a76fc165347ca7',
    },
    'longhao001': {
        'mch_id': '101580578216',
        'appkey': 'a7fcc4d7881cb7d214c2f1e8237cc255',
    },
    'zhongwenzao001': {
        'mch_id': '101530581159',
        'appkey': '0cf810e2fefafcf8c849bd4d3a18cef4',
    },
    'zhaoyasigong001': {
        'mch_id': '101540582328',
        'appkey': 'c70579fb5499b7f804b0c7aac9b8ad19',
    },
    'lilu001': {
        'mch_id': '101540569256',
        'appkey': 'c9333e5bb26acc1ea97af46740120a70',
    },
    'xiaoguozhongjiao001': {
        'mch_id': '101500580274',
        'appkey': '064616a39b8e01aa73bf5c2641e2996f',
    },
    'chenyulingjian': {
        'mch_id': '101520545397',
        'appkey': '9af3ace02e9ed8f1160c48365e120c35',
    },
    'yangweiming001': {
        'mch_id': '101590580685',
        'appkey': '75d2f67aa8abad665a7c7c724502ab87',
    },
    'linhuixupu001': {
        'mch_id': '101500583605',
        'appkey': '91600ab40e8079ffb1a191738c75202d',
    },
    'zhaoyasizhong001': {
        'mch_id': '101530581114',
        'appkey': '1eb8d2bda1baf7ae9783d95739af37fc',
    },
    'yanglei001': {
        'mch_id': '101510580665',
        'appkey': '243733632ffdecaf3fe05a0c8da82646',
    },
    'chenfenglingmin001': {
        'mch_id': '101530569935',
        'appkey': 'd64d461d2b2e78ebbbc36a7df22b8581',
    },
}


def _get_api_id(name):
    return APP_CONF[name]['mch_id']


def _get_api_key(name):
    return APP_CONF[name]['appkey']


@require_GET
def get_charge_qrcode_url(request):
    params = request.GET.dict()
    _LOGGER.info("get_charge_qrcode_url data : %s", params)
    mch_id = _get_api_id(params['name'])
    api_key = _get_api_key(params['name'])
    gateway = 'https://pay.swiftpass.cn/pay/gateway'
    parameter_dict = {
        'service': _get_pay_type(params['type']),
        'version': '2.0',
        'mch_id': mch_id,
        'out_trade_no': int(time.time()),
        'body': 'charge',
        'total_fee': int(float(params['amount']) * 100),
        'mch_create_ip': '127.0.0.1',
        'notify_url': '{}/pay/api/charge/qrcode_pay_notify/'.format(settings.NOTIFY_PREFIX),
        'nonce_str': '3123123213',
    }
    parameter_dict['sign'] = generate_sign(parameter_dict, api_key)
    xml_data = dicttoxml(parameter_dict)
    _LOGGER.info("get_charge_qrcode_url data before charge: %s", xml_data)
    headers = {'Content-Type': 'application/xml'}
    response = requests.post(gateway, data=xml_data, headers=headers, timeout=3).text
    _LOGGER.info("get_charge_qrcode_url data rsp : %s", response)
    d = xmltodict.parse(response)
    t = get_template('qrcode.html')
    html = t.render(Context({'qrcode_url': d['xml']['code_img_url']}))
    return HttpResponse(html)


@require_POST
def qrcode_pay_notify(request):
    _LOGGER.info("qrcode_pay_notify  rsp : %s", request.body)
    return HttpResponse('success', status=200)


@require_GET
def agent_scanpay_notify(request):
    data = dict(request.GET.iteritems())
    _LOGGER.info("agent_scanpay_notify  rsp : %s", data)
    return HttpResponse('SUCCESS', status=200)


@require_GET
def agent_scan_pay(request):
    d = request.GET.dict()
    _LOGGER.info("agent_scan_pay data : %s", d)
    from common.agent import jhzf_scan
    url = jhzf_scan.create_charge(float(d['money']), d.get('type', 'weixin'))
    # return HttpResponse(url, status=200)
    t = get_template('scanpay.html')
    html = t.render(Context({'url': url}))
    return HttpResponse(html)
